#include "ElasticArray.h"
#include <cstring>
#include <cmath>

const double ElasticArray::ELASTICITY = 1.618;
const int ElasticArray::BASE_CAPACITY = 100;

int* ElasticArray::make_array(int capacity) const
{
	int *a = new int[capacity];
	memset(a, 0, capacity * sizeof(int));
	return a;
}

void ElasticArray::ensure_capacity(int requested)
{
	if (requested > capacity_)
	{
		double exp = ceil(log(requested / (double)BASE_CAPACITY) / log(ELASTICITY));
		if (exp < 0) exp = 0;
		
		int required = BASE_CAPACITY * pow(ELASTICITY, exp);
		
		int *new_array = make_array(required);
		memcpy(new_array, array_, size_ * sizeof(int));

		delete [] array_;

		array_ = new_array;
		capacity_ = required;
	}
}

void ElasticArray::push_back(int n)
{
	ensure_capacity(size_ + 1);
	array_[size_++] = n;
}

void ElasticArray::set(int i, int n)
{
	ensure_capacity(i + 1);
	array_[i] = n;
	if (size_ <= i) size_ = i + 1;
}

int ElasticArray::get(int i) const
{
	return (i < size_ && i >= 0) ? array_[i] : 0;
}

int ElasticArray::get_size() const
{
	return size_;
}

ElasticArray& ElasticArray::operator=(const ElasticArray& other)
{
	for (int i = other.get_size() - 1; i >= 0; i--) set(i, other.get(i));
	size_ = other.size_;
	return *this;
}

ElasticArray::ElasticArray(size_t capacity) : size_(0), capacity_(0), array_(NULL)
{
	ensure_capacity(capacity);
}

ElasticArray::ElasticArray(const ElasticArray& other) : size_(0), capacity_(0), array_(NULL)
{
	*this = other;
}

ElasticArray::~ElasticArray()
{
	delete [] array_;
}